using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using CodePlex.SpaceBlock;
using System.Security.Cryptography;
using System.Globalization;
using CodePlex.SpaceBlock.UI.Controls;
using System.Drawing;
using CodePlex.Resourceful;

namespace CodePlex.SpaceBlock.UI
{
    public static class UIUtils
    {
        private static Control __currentSender = null;

        public static Icon GetIcon(Image image)
        {
            return Icon.FromHandle(((Bitmap)image).GetHicon());
        }

        public static void FillWith(Control parent, Control child)
        {
            child.Dock = DockStyle.Fill;
            parent.Controls.Add(child);
        }

        public static bool YesNo(
            IWin32Window owner, 
            Icon icon, 
            string title, 
            string description )
        {

            InputboxForm dialog = new InputboxForm();

            dialog.Title = title;
            dialog.Icon = icon;
    
            dialog.Description = description;
            dialog.MessageBoxButtons = MessageBoxButtons.YesNo;
           
            DialogResult result = dialog.ShowDialog(owner);

            return result == DialogResult.Yes;
        }


        public static string Inputbox(
            IWin32Window owner,
            Icon icon,
            string title,
            string description,

            string prompt,
            bool hideText,
            Control customControl)
        {
            return UIUtils.Inputbox(owner, icon, title, description, prompt, hideText, customControl, null, null);
        }

        public static string Inputbox(
            IWin32Window owner, 
            Icon icon, 
            string title, 
            string description, 
            
            string prompt, 
            bool hideText,
            Control customControl,
            string customButtonText,
            Fn<string> customButtonAction)
        {
            InputboxForm dialog = new InputboxForm();

            dialog.Title = title;
            dialog.Icon = icon;
            dialog.Prompt = prompt;
            dialog.Description = description;
            dialog.HideText = hideText;
            dialog.CustomControl = customControl;
            dialog.CustomButtonText = customButtonText;


            if (owner == null)
            {
                dialog.StartPosition = FormStartPosition.CenterScreen;
            }

            DialogResult result = dialog.ShowDialog(owner);

            if (result == DialogResult.OK)
            {
                return dialog.Value;
            }
            else if (result == DialogResult.Retry)
            {
                if (customButtonAction != null)
                {
                    return customButtonAction();
                }
            }
           
            return null;
        }


        public static void MessageBox(string message, params object[] parameters)
        {
           // System.Windows.Forms.MessageBox.Show(string.Format(message, parameters));

            InputboxForm dialog = new InputboxForm();
            dialog.ShowIcon = false;
            dialog.Title = "";
            //dialog.Icon = icon;

            dialog.Description = string.Format(message, parameters);
            dialog.MessageBoxButtons = MessageBoxButtons.OK;

            dialog.ShowDialog();

        }

        public static void ConfigureForDragDrop(Control control, Predicate<Control> senderIsValid, Operation<Control, object[]> consumer)
        {
            control.AllowDrop = true;

            control.DragDrop += delegate(object sender, System.Windows.Forms.DragEventArgs e)
            {
                string text = e.Data.GetData(DataFormats.Text).ToString();
                string[] tokens = text.Split(',');

                object[] objects = StringMarshaller.FromString(tokens);
                consumer(__currentSender, objects);

                __currentSender = null;

                control.Tag = false;
               
              
            };

            control.DragEnter += delegate(object sender, System.Windows.Forms.DragEventArgs e)
            {
                if (e.Data.GetDataPresent(DataFormats.Text) && senderIsValid(__currentSender))
                {
                    e.Effect = DragDropEffects.Copy;
                }
                else
                {
                    e.Effect = DragDropEffects.None;
                }
             
            };

            
            control.MouseUp += delegate
            {
                __currentSender = null;
            };

            control.MouseDown += delegate(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                if (__currentSender == null)
                {
                    __currentSender = control;
                }
            };

            
            control.MouseMove += delegate(object sender, MouseEventArgs e)
            {
                if (__currentSender==null || e.Button == MouseButtons.Right)
                {
                    return;
                }

                string str = "";

                ListView listView = control as ListView;
                if (listView != null)
                {
                    str = UIUtils.GetItemText(listView);
                }

                TreeView treeView = control as TreeView;
                if (treeView != null)
                {
                    str = UIUtils.GetItemText(treeView);
                }

                DataGridView grid = control as DataGridView;
                if (grid != null)
                {
                    str = UIUtils.GetItemText(grid);
                }

                if (str == "")
                {
                    return;
                }

                control.DoDragDrop( str, DragDropEffects.Copy | DragDropEffects.Move);
            };


        }


        public static string GetFullPath(Control control)
        {
            List<string> tokens = new List<string>();

            while (control != null)
            {
                string name = control.Name;
                if (string.IsNullOrEmpty(name))
                {
                    name = control.GetType().Name;
                }
                tokens.Add(name);
                control = control.Parent;
            }

            
            tokens.Reverse();

            return string.Join(".", tokens.ToArray());

        }

       
        public static string GetItemText(ListView listView)
        {

            string[] rt = new string[listView.SelectedItems.Count];

            for (int i = 0;i<rt.Length;i++)
            {
                ListViewItem item = listView.SelectedItems[i];

                rt[i] = StringMarshaller.ToString(item.Tag);

            };

            return string.Join(",", rt);
        }

        public static string GetItemText(DataGridView grid)
        {

            string[] rt = new string[grid.SelectedRows.Count];

            for (int i = 0; i < rt.Length; i++)
            {
                DataGridViewRow item = grid.SelectedRows[i];

                rt[i] = StringMarshaller.ToString(item.Tag);
            };

            return string.Join(",", rt);
        }

        public static string GetItemText(TreeView treeView)
        {
            if (treeView.SelectedNode == null)
            {
                return "";
            }
            
            return  StringMarshaller.ToString(treeView.SelectedNode.Tag);
        }

        public static void MinimizeToTray(Form target, Icon icon) {


            NotifyIcon notify = new NotifyIcon();

            notify.Icon = icon;
            notify.Text = target.Text;
            notify.Visible = true;


            EventHandler restore = delegate
            {
                target.Show();
                target.WindowState = FormWindowState.Normal;
            };

            notify.DoubleClick += restore;

            target.Resize += delegate
            {
                if (FormWindowState.Minimized == target.WindowState)
                {
                    target.Hide();
                }
            };


            ContextMenu m = new ContextMenu();

            m.MenuItems.Add("Restore", restore).DefaultItem = true;
           

            m.MenuItems.Add("Exit", delegate
            {
               Application.Exit();
            });

            notify.ContextMenu = m;

            
            target.FormClosed += delegate
            {
                notify.Dispose();
            };

            
        }


    }
}
